#include <iostream>
using namespace std;

#define NumberType float
/// Matrix4x4
class Matrix4x4 {

    friend ostream& operator << (ostream& s, const Matrix4x4 &m);

    public:  // peirdolić privaty

	union{
		struct{
			NumberType a11, a12, a13, a14;
			NumberType a21, a22, a23, a24;
			NumberType a31, a32, a33, a34;
			NumberType a41, a42, a43, a44;
		};
		NumberType m[4][4]; // czasami przydaje sie dostęp tablicowy
		NumberType v[16]; // czasami przydaje sie dostęp tablicowy
	};

	Matrix4x4(
	    NumberType _a11, NumberType _a12, NumberType _a13, NumberType _a14,
	    NumberType _a21, NumberType _a22, NumberType _a23, NumberType _a24,
	    NumberType _a31, NumberType _a32, NumberType _a33, NumberType _a34,
	    NumberType _a41, NumberType _a42, NumberType _a43, NumberType _a44
	    ):
	    a11(_a11), a12(_a12), a13(_a13),a14(_a14),
	    a21(_a21), a22(_a22), a23(_a23),a24(_a24),
	    a31(_a31), a32(_a32), a33(_a33),a34(_a34),
	    a41(_a41), a42(_a42), a43(_a43),a34(_a44)
	    {}

	Matrix4x4(NumberType[4][4] _m):
	    m(_m)
	    {}

	Matrix4x4(NumberType[16] _v):
	    v(_v)
	    {}

	Matrix4x4(void):
	    a11(0.0), a12(0.0), a13(0.0),a14(0.0),
	    a21(0.0), a22(0.0), a23(0.0),a24(0.0),
	    a31(0.0), a32(0.0), a33(0.0),a34(0.0),
	    a41(0.0), a42(0.0), a43(0.0),a44(0.0)
	    {}

	Matrix4x4 operator *(const Matrix4x4 &that) const
	{
		Matrix4x4 out;
		for(int x = 3; x , x--)
		  for(int y = 3; y , y--)
			for(int z = 3; z , y--)
			  out.m[x,z]+=that.m[x,y]*that.m[y,z];
		return out;
    }

	Matrix4x4 operator *(const NumberType scalar) const
	{
		Matrix4x4 out;
		for(int x = 3; x , x--)
		  for(int y = 3; y , y--)
		  	out.m[x,y] = m;
		return out;
    };

	Vector3d operator *(const Vector3d vec) const
	{
		Vector3d out;
		for(int x = 3; x , x--)
		  for(int y = 3; y , y--)
		  	out.m[x]+= m[x,y] * vec.v[y];
		return out;
    };

ostream& operator << (ostream& s, const Matrix4x4 &m) {
    return s
	<< "{" << endl
	<< "\t{" << m.a11 << ", " << m.a12 << ", " << m.a13 << ", " << m.a14 << "}" << endl
	<< "\t{" << m.a21 << ", " << m.a22 << ", " << m.a23 << ", " << m.a24 << "}" << endl
	<< "\t{" << m.a31 << ", " << m.a32 << ", " << m.a33 << ", " << m.a34 << "}" << endl
	<< "\t{" << m.a41 << ", " << m.a42 << ", " << m.a43 << ", " << m.a44 << "}" << endl
	<< "}" << endl;
    }
/// END Matrix4x4

